package com.blocks.blocks;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import com.blocks.ScriptBlocksApplication;

public class ScriptEvaluator {
	private Invocable inv = null;
	Object obj = null;

	public void evalutate(String fileName, Block block) {
		try {
			ScriptEngineManager manager = new ScriptEngineManager();
			ScriptEngine engine = manager.getEngineByName("JavaScript");
			engine.put("thisBlock", block);			
			InputStream inputStream = new FileInputStream(fileName);
			if(inputStream==null){
				System.out.println("Could not Open File:" + fileName);
				return;
			}
			engine.eval(new InputStreamReader(inputStream));		
			inv = (Invocable) engine;
			obj = engine.get("block");
		} catch (ScriptException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//App loop
	public void evalutate(String fileName) {
		try {
			ScriptEngineManager manager = new ScriptEngineManager();
			ScriptEngine engine = manager.getEngineByName("JavaScript");			
			InputStream inputStream = new FileInputStream(fileName);
			if(inputStream==null){
				return;
			}
			engine.eval(new InputStreamReader(inputStream));		
			inv = (Invocable) engine;
			obj = engine.get("application");
		} catch (ScriptException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void setupScript() {
		if(obj !=null && inv!=null){
			try {
				inv.invokeMethod(obj, "setup", "Testing one !!");
			} catch (NoSuchMethodException e) {	
				System.out.println(obj);
				e.printStackTrace();
			} catch (ScriptException e) {	
				System.out.println(obj);
				e.printStackTrace();
			}
		}
	}

	public void loopScript(float tpf) {
		if(obj !=null && inv!=null){
			try {	
				inv.invokeMethod(obj, "loop", "Testing one !!", tpf);
			} catch (NoSuchMethodException e) {
				System.out.println(obj);
				e.printStackTrace();
			} catch (ScriptException e) {
				System.out.println(obj);
				e.printStackTrace();
			}
		}
	}
	/**
	 * BUFFER USED FOR CUT AND PASTE
	 * @param buffer
	 */
	public void evalutateUndoBuffer(String buffer) {
		StringBuffer sb = new StringBuffer();
		sb.append("importPackage(com.blocks.blocks);\n");
		sb.append("importPackage(com.blocks);\n");
		sb.append("importPackage(com.blocks.model);\n");
		sb.append("importPackage(com.jme3.math);\n");
		sb.append("importPackage(java.lang);\n");
		sb.append("var pasteObject = new Object();\n");
		sb.append("pasteObject.paste = function() {\n");
		sb.append(buffer);
		//attach the buffer to the new focus block
		Block undoBlock  = ScriptBlocksApplication.getInstance().getUndoBlock();
		String undoBlockVariable = ScriptBlocksApplication.getInstance().getUndoBlockVariable();
		sb.append("focusBlock.attachChild("+undoBlockVariable+");\n");
		sb.append("}\n");
		
		try {
			ScriptEngineManager manager = new ScriptEngineManager();
			ScriptEngine engine = manager.getEngineByName("JavaScript");	
			engine.put("focusBlock", undoBlock);
			engine.eval(sb.toString());		
			inv = (Invocable) engine;
			obj = engine.get("pasteObject");
		} catch (ScriptException e) {
			e.printStackTrace();
		} 
	}
	/**
	 * BUFFER USED FOR CUT AND PASTE
	 * @param buffer
	 */
	public void evalutateBuffer(String buffer) {
		StringBuffer sb = new StringBuffer();
		sb.append("importPackage(com.blocks.blocks);\n");
		sb.append("importPackage(com.blocks);\n");
		sb.append("importPackage(com.blocks.model);\n");
		sb.append("importPackage(com.jme3.math);\n");
		sb.append("importPackage(java.lang);\n");
		sb.append("var pasteObject = new Object();\n");
		sb.append("pasteObject.paste = function() {\n");
		sb.append(buffer);
		//attach the buffer to the new focus block
		Block focusBlock  = ScriptBlocksApplication.getInstance().getFocusBlock();
		String copiedBlockVariable = ScriptBlocksApplication.getInstance().getCopyBlockVariable();
		sb.append("focusBlock.attachChild("+copiedBlockVariable+");\n");
		sb.append("}\n");
		
		try {
			ScriptEngineManager manager = new ScriptEngineManager();
			ScriptEngine engine = manager.getEngineByName("JavaScript");	
			engine.put("focusBlock", focusBlock);
			engine.eval(sb.toString());		
			inv = (Invocable) engine;
			obj = engine.get("pasteObject");
		} catch (ScriptException e) {
			e.printStackTrace();
		} 
	}
	/**
	 * PASTE SCRIPT CALL
	 */
	public void pasteScript() {
		if(obj !=null && inv!=null){
			try {	
				inv.invokeMethod(obj, "paste");
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (ScriptException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	public String exportScript() {
		if(obj !=null && inv!=null){
			try {	
				String exportValue = (String)inv.invokeMethod(obj, "scriptExport", "Testing one !!");
				return exportValue; 
			} catch (NoSuchMethodException e) {
				//DO NOTHING
			} catch (ScriptException e) {
				e.printStackTrace();
			}
		}
		return "";
	}
	public void useScript() {
		if(obj !=null && inv!=null){
			try {	
				inv.invokeMethod(obj, "use");
			} catch (NoSuchMethodException e) {
				//DO NOTHING
			} catch (ScriptException e) {
				e.printStackTrace();
			}
		}
		
	}
}
